/*
 * pgsql_function testing function calls with Postgresql and dbConnect API
 * Copyright (C) 2004 Johnathan Ingram, jingram@rogueware.org
 *
 * This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  US
 *
 * Note: This example requires the Func1Test function as defined in the SQL for Postgresql
 */


#include <iostream>
#include <string>


#include "dbconn/dbconnect.h"

using namespace std;


int 
main(
      int argc, char** argv)
{
   DbConnectionVar driver;
   DbQueryVar      conn;
   string          sqlQuery;
      
   try
   {
      driver = new DbConnection(DbConnection::POSTGRESQL, "./dbconnect.cfg");

      // Connect to the database. 
      driver->connect("dbconnect", "letmein", "dbConnectDB", "localhost");

      // Get a query connection object
      conn = driver->requestQueryConnection();

      
      // Test 1: Postgresql Call to an Existing Function
      cout << endl << endl;
      cout << "TEST 1: Postgresql Call to an Existing Function" << endl;
      cout << "---------------------------" << endl;
      
      // Note:  
      //  Because in Postgresql you cannot give names to the parameters in functions, dbConnect API
      //    will assign parameter names as follows: :(
      //      First  Parameter: param1   Use bindParam("param1")->
      //      Second Parameter: param2   Use bindParam("param2")->
      //      .... (and so forth)
      //  A result from a function will always be returned in a bind parameter named "result"
      sqlQuery = 
         "FUNC1TEST";
      conn->command(sqlQuery);      
      conn->bindParam("param1")->setLong(5);
      //conn->bindParam("param2")->setLong(10);
      conn->execute();
      
      cout << "Function Result : " << conn->bindParam("result")->asString() << endl;
      cout << "Expecting Result: 10" << endl;



      // Test 2: Postgresql Call to an non-existing Function
      cout << endl << endl;
      cout << "TEST 2: Postgresql Call to an non-existing Function" << endl;
      cout << "---------------------------" << endl;
      
      sqlQuery = 
         "FUNC55TEST";
      conn->command(sqlQuery);      
      conn->bindParam("param1")->setLong(5);
      conn->bindParam("param2")->setLong(10);
      conn->execute();
      
   }
   catch(BaseException &ex)
   {
      // Only need to catch a single exception. Can use 'name' etc to determine the actual exception
      cout << "DbConnect Exception: " << ex.name << endl 
           << "  " << ex.code << " : " << ex.description << endl;
   }
   catch(...)
   {
      cout << "An Unknown exception has been trapped!\n" << endl;
   }
   cout << endl;
        
   // The 'conn' and 'driver' objects are smart pointers and will cleanup as soon as they go out of scope      

   return 0;
}
